@file:OptIn(ExperimentalAnimationApi::class)

package lee.vioson.ebook.ui

import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.tween
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NamedNavArgument
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavDeepLink
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.navArgument
import com.google.accompanist.navigation.animation.AnimatedNavHost
import com.google.accompanist.navigation.animation.composable
import lee.vioson.ebook.data.AppContainer
import lee.vioson.ebook.ui.components.BookDetail
import lee.vioson.ebook.ui.components.Feedback
import lee.vioson.ebook.ui.components.FeedbackDetail
import lee.vioson.ebook.ui.components.FeedbackHistory
import lee.vioson.ebook.ui.components.LoginScreen
import lee.vioson.ebook.ui.components.MainScreen
import lee.vioson.ebook.ui.components.OtpVerification
import lee.vioson.ebook.ui.components.PurchaseHistory
import lee.vioson.ebook.ui.components.ReadScreen
import lee.vioson.ebook.ui.components.RegisterScreen
import lee.vioson.ebook.ui.components.SearchScreen
import lee.vioson.ebook.ui.components.SetPassword
import lee.vioson.ebook.ui.components.VipScreen
import lee.vioson.ebook.utils.BookJumper

/**
 *Author:viosonlee
 *Date:2023/6/2
 *DESCRIPTION:
 */
@Composable
fun MainAnimateNavGraph(
    modifier: Modifier = Modifier,
    appContainer: AppContainer,
    navController: NavHostController
) {

    AnimatedNavHost(
        navController = navController,
        startDestination = AppDestinations.MAIN_ROUTE,
        modifier = modifier,
    ) {
        setComposable(route = AppDestinations.MAIN_ROUTE) {
            MainScreen(navController, appContainer)
        }
        setComposable(route = AppDestinations.SEARCH_ROUTE) {
            SearchScreen(navController, appContainer)
        }
        setComposable(route = AppDestinations.LOGIN_ROUTE) {
            LoginScreen(navController, appContainer)
        }
        setComposable(route = AppDestinations.REGISTER_ROUTE) {
            RegisterScreen(navController, appContainer)
        }
        setComposable(
            route = AppDestinations.BOOK_DETAIL_ROUTE,
            arguments = listOf(navArgument(Constants.bookId) { defaultValue = "" })
        ) {
            val bookId = it.arguments?.getString(Constants.bookId)
            bookId?.let { it1 -> BookDetail(navController, appContainer, it1) }
        }
        setComposable(route = AppDestinations.READ_ROUTE) {
            if (BookJumper.INSTANCE.book != null && BookJumper.INSTANCE.chapter != null) {
                ReadScreen(
                    BookJumper.INSTANCE.chapter!!,
                    BookJumper.INSTANCE.book!!,
                    navController, appContainer
                )
            }
        }
        setComposable(route = AppDestinations.SET_PASSWORD_ROUTE) {
            SetPassword(navController, appContainer)
        }
        setComposable(route = AppDestinations.OTP_VERIFICATION_ROUTE,
            arguments = listOf(
                navArgument(Constants.email) { defaultValue = "" },
                navArgument(Constants.password) { defaultValue = "" }
            )
        ) {
            val email = it.arguments?.getString(Constants.email) ?: ""
            val password = it.arguments?.getString(Constants.password) ?: ""
            val type = it.arguments?.getString(Constants.type) ?: "1"
            OtpVerification(navController, appContainer, email, password, type.toInt())
        }
        setComposable(route = AppDestinations.PURCHASE_HISTORY) {
            PurchaseHistory(navController)
        }
        setComposable(
            route = AppDestinations.FEEDBACK,
            arguments = listOf(navArgument(Constants.msgId) { defaultValue = "" })
        ) {
            val msgId = it.arguments?.getString(Constants.msgId)
            Feedback(msgId,navController, appContainer)
        }
        setComposable(route = AppDestinations.FEEDBACK_DETAIL, arguments = listOf(
            navArgument(Constants.msgId) { defaultValue = "" }
        )) {
            val msgId = it.arguments?.getString(Constants.msgId)
            msgId?.let { it1 ->
                FeedbackDetail(msgId = it1, navController, appContainer)
            }
        }
        setComposable(route = AppDestinations.FEEDBACK_HISTORY) {
            FeedbackHistory(navController, appContainer)
        }

        setComposable(route = AppDestinations.VIP_SCREEN) {
            VipScreen(navController)
        }
    }
}

const val speedAnimation = 500

@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.setComposable(
    route: String,
    arguments: List<NamedNavArgument> = emptyList(),
    deepLinks: List<NavDeepLink> = emptyList(),
    content: @Composable AnimatedVisibilityScope.(NavBackStackEntry) -> Unit
) {
    return composable(
        route = route,
        arguments = arguments,
        deepLinks = deepLinks,
        enterTransition = {
            slideIntoContainer(
                AnimatedContentScope.SlideDirection.Left, animationSpec = tween(speedAnimation)
            )
        },
        exitTransition = {
            slideOutOfContainer(
                AnimatedContentScope.SlideDirection.Left, animationSpec = tween(speedAnimation)
            )
        },
        popEnterTransition = {
            slideIntoContainer(
                AnimatedContentScope.SlideDirection.Right, animationSpec = tween(speedAnimation)
            )
        },
        popExitTransition = {
            slideOutOfContainer(
                AnimatedContentScope.SlideDirection.Right, animationSpec = tween(speedAnimation)
            )
        },
        content = content
    )
}